import java.util.ArrayList;
import java.util.List;

public class PaperList {
    private final String teacher;
    private final List<Paper> papers;
    private final PaperSelection selections = new PaperSelection();
    private PaperSelectionStrategy strategy = new RandomSelectionStrategy(); // 默认随机策略

    public PaperList(String teacher, List<Paper> papers) {
        if (teacher == null || teacher.isEmpty()) {
            throw new IllegalArgumentException("教师姓名不能为空");
        }
        if (papers == null) {
            throw new NullPointerException("论文清单不能为null");
        }
        this.teacher = teacher;
        this.papers = new ArrayList<>(papers); // 防御性拷贝
    }

    public void setSelectionStrategy(PaperSelectionStrategy strategy) {
        if (strategy == null) {
            throw new NullPointerException("策略不能为null");
        }
        this.strategy = strategy;
    }

    private List<Paper> getUnselectedPapersByType(PaperType type) {
        List<Paper> result = new ArrayList<>();
        for (Paper paper : papers) {
            if (!selections.isSelected(paper)) {
                if (type == PaperType.Any) {
                    result.add(paper);
                } else {
                    String paperTypeName = paper.getClass().getSimpleName();
                    if (type.toString().equals(paperTypeName)) {
                        result.add(paper);
                    }
                }
            }
        }
        return result;
    }

    public List<Paper> selectPaper(Student student) throws NoEnoughPapersException {
        if (student == null) {
            throw new NullPointerException("学生不能为null");
        }
        // 检查学生是否已选择过论文
        if (selections.getSelections().values().contains(student)) {
            throw new IllegalArgumentException("学生" + student.getName() + "已选择过论文");
        }

        List<Paper> availablePapers = getUnselectedPapersByType(student.getPreferredPaperType());
        if (availablePapers.size() < student.getPreferredQuantity()) {
            throw new NoEnoughPapersException(
                    student.getName(),
                    student.getPreferredQuantity(),
                    availablePapers.size()
            );
        }

        List<Paper> selected = strategy.selectPapers(availablePapers, student.getPreferredQuantity());
        for (Paper paper : selected) {
            selections.addSelection(student, paper);
        }
        return selected;
    }

    public PaperSelection getSelectionResult() {
        // 返回防御性拷贝（此处简化，实际可通过构造新对象实现深拷贝）
        return selections;
    }
}